<?php

namespace coser;

use PDO;
use coser\Config;

class Db
{
    //数据库连接实例
	protected static $instance = [];
	//查询次数
    public static $queryTimes = 0;
    //执行次数
    public static $execTimes = 0;
	//连接名
    protected static $linkName = '';
    //表名
    public static $table = '';
	//别名
    public $as = '';
	//查询字段
	public $field = '*';
	//连表
	public $join = '';
	//连表条件
	public $on = '';
    //条件
    public $where = '';
	//组合
    public $group = '';
    //limit
    public $limit = '';
    //排序
    public $by = '';


    /*
     *[连接数据库 返回数据库实例]
     * @param $config  连接配置
     * @param $class
     * @return object
     */
    public function __construct()
    {
        //检查mysql是否实例化
        if(self::$instance instanceof self){
            return self::$instance;
        }

        //获取处理配置
		$config = Config::get('database');
        $dsn = $config['type'].':host='.$config['hostname'].';dbname='.$config['database'].';charset='.$config['charset'];

        //连接
        self::$instance = new PDO($dsn,$config['useranme'],$config['password']);

        //返回
        return self::$instance;
    }

    //设置操作表
    public static function name($table)
    {
        self::$table = $table;
		return new self;
    }

    //条件解析
    public function where($key='',$val='')
    {
        if(is_array($key)){
            //解析条件
            $where = self::parseWhere($key);
        }else{
            $where = $key .' = "'. $val.'"';
        }
	
        $this->where = ' where ' . $where;
		
		return $this;
    }

	//解析条件
    public static function parseWhere($where)
    {
		$fem = 0;
		$end = count($where) - 1;
		
		$text = '';
		foreach($where as $key => $val){
		    if(is_array($val)){
                //里条件
                $text  .= $key . self::inWhere($val);
            }else{
                $text .= $key .' = "'. $val.'"';

            }

            $text .= $fem == $end ?  '' : ' and ';
			$fem++;
		}
		return $text;
    }

    //里条件
    public static function inWhere($val)
    {
        $text = '';
        switch($val[0]){
            case '>':
                $text = ' > '. $val[1];
                break;
            case '<':
                $text = ' < '. $val[1];
                break;
            case 'between':
                $text = ' between '. $val[1]. ' and '.$val[2];
                break;
            case 'like':
                $text = ' like "'. $val[1].'"';
                break;
            default:
                $text = ' '.$val[0] .' '. $val[1];
                break;
        }

        return $text;
    }
	
	//表别名
	public function uas($val)
    {

        $this->as = ' as '.$val.' ';
		
		return $this;
    }
	
	//取字段
	public function field($val)
    {

        $this->field = ' '.$val.' ';
		
		return $this;
    }
	
	//联表
	public function ujoin($table,$as,$type)
	{
        $this->join = $type .' JOIN ' . $table . ' as ' . $as;
		
		return $this;
	}
	
	//联表条件
	public function uon($on)
	{
        $this->on = ' on '.$on;
		
		return $this;
	}
	
	//组合条件
    public function group($group)
    {
        $this->group = ' group by '.$group;

        return $this;
    }

    //组合条件
    public function limit($int,$num)
    {
        $this->limit = ' LIMIT '. $int .','.$num;

        return $this;
    }

    //排序
    public function by($by)
    {
        $this->by = ' order by '.$by;

        return $this;
    }
	
	//插入
	public function insert($data)
	{
	    foreach ($data as $key => $val){
	        $data[$key] = '"'.$val.'"';
        }

		$keys = implode(',', array_keys($data));
        $values = array_values($data);
		
        $place = implode(',', $data);

        $sql = "insert into ".self::$table." ($keys) VALUES ($place)";

		return $this->gotelang($sql,'add');
	}
	
	
	//查询列表
	public function select()
	{
        $sql = "SELECT ".$this->field." FROM ".self::$table . $this->as . $this->join . $this->on .$this->where . $this->group . $this->by . $this->limit;

		return $this->gotelang($sql,'select');
	}
	
	//查询
	public function find()
	{
        $sql = "SELECT ".$this->field." FROM ". self::$table . $this->as . $this->join . $this->on .$this->where . $this->group . $this->by;

		return $this->gotelang($sql,'find');
	}

    //更新
    public function update($data)
    {
        $sql = "UPDATE " . self::$table . $this->set($data) . $this->where;

        return $this->gotelang($sql,'update');
    }

    //更新数据
    public function set($data)
    {
        $fem = 0;
        $end = count($data) - 1;

        $text = ' SET ';
        foreach($data as $key => $val){

            $text .= $key .' = "'. $val.'"';

            $text .= $fem == $end ?  '' : ',';
            $fem++;
        }
        return $text;
    }

    //统计
    public function count()
    {
        $sql = "SELECT count(*) FROM ".self::$table . $this->as . $this->join . $this->on . $this->where  . $this->limit;

        return $this->gotelang($sql,'count');
    }
	
	//sql执行
	public function gotelang($sql,$type)
	{
		// 设置 PDO 错误模式，用于抛出异常
		self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		var_dump($sql);
		try {

			switch($type){
				case 'add':
                    $result = self::$instance->exec($sql);
					break;
                case 'update':
                    $result = self::$instance->exec($sql);
                    break;
				case 'select':
					$stmt = self::$instance->prepare($sql);
					$stmt->execute();
					$stmt->setFetchMode(PDO::FETCH_ASSOC); 
					$result = $stmt->fetchAll();
					break;
				case 'find':
					$stmt = self::$instance->prepare($sql); 
					$stmt->execute();
					$stmt->setFetchMode(PDO::FETCH_ASSOC); 
					$res = $stmt->fetchAll();
					$result = $res[0];
					break;
				default :
                    $pdostatement = self::$instance->query($sql);
                    $result = $pdostatement->fetchColumn();
                    break;
			}
	
			return $result;
		}catch(PDOException $e){
			echo $sql . "<br>" . $e->getMessage();
			return 0;
	
		}
		
	}

}